import { VNode, h, App, render, createApp } from "vue";
import { DialogOptions, dialog } from "./popup/dialog";
import { DrawerOptions, drawer } from "./popup/drawer";
import { message as messageInstance } from "./popup/message";
import { PopupEvent } from "./popup/type";

import PageComponent from "./page-component.vue";
import { v4 as uuidv4 } from "uuid";
import { MessageBoxOptions, messageBox } from "./popup";
export interface IPage {
	/**
	 * 成功消息
	 * @param message 消息内容
	 */
	showSuccMsg(message: string): void;
	/**
	 * 失败消息
	 * @param message 消息内容
	 */
	showErrorMsg(message: string): void;
	/**
	 * 消息确认框
	 * @param opts
	 */
	showMsgBox(opts: MessageBoxOptions): void;
	/**
	 * 弹出框
	 * @param opts
	 */
	showDialog(opts: DialogOptions): Promise<PopupEvent>;
	/**
	 * 侧边栏
	 * @param opts
	 */
	showDrawer(opts: DrawerOptions): PopupEvent;
	/**
	 * 创建布局vnode,通过动态路由渲染到页面上
	 */
	repaint(vnode: VNode): void;
}
export abstract class Page implements IPage {
	name: string;
	// 页面的随机id，便于页面重绘时找到该id进行render
	private pageId = uuidv4();
	private vm: App | undefined = undefined;
	constructor(name: string) {
		this.name = name;
	}
	protected abstract getLayout(fn: Function): VNode;
	showSuccMsg(message: string): void {
		messageInstance.open({
			title: "系统提示",
			message,
			type: "success",
		});
	}
	showErrorMsg(message: string): void {
		messageInstance.open({
			title: "系统提示",
			message,
			type: "error",
		});
	}
	showMsgBox(opts: MessageBoxOptions): void {
		messageBox.open(opts);
	}
	showDialog(opts: DialogOptions): PopupEvent | any {
		return dialog.open(opts);
	}
	showDrawer(opts: DrawerOptions): PopupEvent {
		return drawer.open(opts);
	}
	repaint(): void {
		// 判断dom是否存在
		const pageDom = document.getElementById(this.pageId);
		if (pageDom) {
			render(this.getLayout(this.unMount), pageDom);
			//TODO 使用路由渲染会出现两个VNode，第一个VNode不会进行更新，所以当存在两个VNode时需要删除第一个
			if (pageDom.children.length >= 2) {
				pageDom.removeChild(pageDom.children[0]);
			}
		}
	}

	unMount() {
		const pageDom = document.getElementById(this.pageId);
		this.vm?.unmount();
		render(h("div"), pageDom!);
	}

	abstract getVNode(): VNode;
	/**
	 * 返回一个携带id的VNode,为在重绘时可以查找到可重绘的dom
	 * @param vnode
	 * @returns
	 */
	protected createPageComponent(): VNode {
		if (this.pageId) {
			document.getElementById(this.pageId)?.remove();
			this.pageId = uuidv4();
		}
		return h(PageComponent, {
			id: this.pageId,
			key: this.pageId,
			style: {
				width: "100%",
				height: "100%",
			},
			repaint: () => this.repaint(),
			unMount: () => this.unMount(),
		});
	}
	createComponent(id: Element): App<Element> | undefined {
		this.vm = createApp(PageComponent, {
			id: this.pageId,
			key: this.pageId,
			style: {
				width: "100%",
				height: "100%",
			},
			repaint: () => this.repaint(),
			unMount: () => this.unMount(),
		});
		this.vm?.mount(id);
		return this.vm;
	}
}
